package org.essilab.analyzer.analyzer.db;

import java.io.File;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.essilab.analyzer.Configuration.BlockedFolder;
import org.essilab.analyzer.Configuration.Config;
import org.essilab.analyzer.Configuration.FileTerm;
import org.essilab.analyzer.analyzer.Term;

/**
 * This class is used to parse all the files created from the Wiktionary dump
 * and store them is a DB.
 *
 * @author Mohamed-Amine Chouchene, Ahcène Idinarere, Vincent Nock, Alain
 * Janin-Manificat
 * @see XMLParser
 */
public class Parser {
//36340

    public static String mainFolder = "/";
    private String folder = "terms/";
    private String absoluteRoot = null;
    private ServiceDAO service = null;
    private BlockedFolder bf = null;
    private Integer maxReqTerm = 50000;

    /**
     * Parser contructor. Load the config file "config.ini". Init ServiceDAO
     * with user/password in "config.ini".
     */
    public Parser() {
        this.absoluteRoot = mainFolder + folder;
        service = new ServiceDAO(Config.get("userDB"), Config.get("passwordDB"));
        bf = new BlockedFolder("folder.txt");
        if(null!=Config.get("maxReqTerm"))
        	maxReqTerm = Integer.valueOf(Config.get("maxReqTerm"));
    }

    /**
     * Constructor for Parser without ServiceDAO.
     * @param withDAO useless
     */
    public Parser(boolean withDAO) {
        this.absoluteRoot = mainFolder + folder;
        Config.setFile("config.ini");
    }

    /**
     * Parse all the stored terms and save them in the DB.
     *
     * @param saveTerm boolean - Tell whether or not the Term has to be saved in
     * DB.
     */
    private void parser(boolean saveTerm) {
        int count = 0;
        File f = new File(this.absoluteRoot);
        for (String el : f.list()) {
            File t = new File(this.absoluteRoot + el);
            if (t.isDirectory() && !bf.isBlockedFolder(t.getPath())) {
                String[] lists = t.list();
                if ((lists.length + count) > maxReqTerm) {
                    break;
                }
                for (String e : lists) {
                    File file = new File(this.absoluteRoot + el + "/" + e);
                    if (file.isFile()) {
                        Term term = parser(file);
                        if (saveTerm) {
                            saveTerm(term);
                        } else {
                            saveRelation(term);
                        }
                        count++;
                    }
                }
                bf.blockedNewFolder(t.getPath());
            }
        }
        this.bf.close();
        if(0==count)
        	System.out.println("Finish!!!!!");
    }

    /**
     * Create a term from the informations stored in given File.
     *
     * @param f File - File where the informations about a term are stored.
     * @return Term - The term created from the given file.
     */
    @SuppressWarnings("unchecked")
    public Term parser(File f) {
        try {
            FileTerm ft = new FileTerm(f);
            Term term = new Term();
            if (null != ft.getSection("info")) {
                Map<String, String> info = (Map<String, String>) ft.getSection("info");
                term.setTitle(info.get("title"));
                term.setCreatedAt(info.get("created_at"));
                term.setLang(info.get("lang"));
            }
            if (null != ft.getSection("types")) {
                term.setTypes((List<String>) ft.getSection("types"));
            }

            if (null != ft.getSection("abbreviations")) {
                term.setAbbreviations((List<String>) ft.getSection("abbreviations"));
            }

            if (null != ft.getSection("almost_synonymous")) {
                term.setAlmostSynonymous((List<String>) ft.getSection("almost_synonymous"));
            }

            if (null != ft.getSection("antonyms")) {
                term.setAntonym((List<String>) ft.getSection("antonyms"));
            }

            if (null != ft.getSection("derives")) {
                term.setDerives((List<String>) ft.getSection("derives"));
            }

            if (null != ft.getSection("dimintives")) {
                term.setDimintives((List<String>) ft.getSection("dimintives"));
            }

            if (null != ft.getSection("errors")) {
                term.setError((List<String>) ft.getSection("errors"));
            }

            if (null != ft.getSection("form_adjectif")) {
                term.setfAdj((List<String>) ft.getSection("form_adjectif"));
            }

            if (null != ft.getSection("form_adjectif_undefine")) {
                term.setfAdjIndef((List<String>) ft.getSection("form_adjectif_undefine"));
            }

            if (null != ft.getSection("form_interjectif")) {
                term.setfInterj((List<String>) ft.getSection("form_interjectif"));
            }

            if (null != ft.getSection("form_locution_adverb")) {
                term.setfLAdv((List<String>) ft.getSection("form_locution_adverb"));
            }

            if (null != ft.getSection("form__locution_noun")) {
                term.setfLNoun((List<String>) ft.getSection("form__locution_noun"));
            }

            if (null != ft.getSection("form_locution_verb")) {
                term.setfLVerb((List<String>) ft.getSection("form_locution_verb"));
            }

            if (null != ft.getSection("form_noun")) {
                term.setfNoun((List<String>) ft.getSection("form_noun"));
            }

            if (null != ft.getSection("form_verb")) {
                term.setfVerb((List<String>) ft.getSection("form_verb"));
            }

            if (null != ft.getSection("holonyms")) {
                term.setHolonyms((List<String>) ft.getSection("holonyms"));
            }

            if (null != ft.getSection("hyperonyms")) {
                term.setHyperonyms((List<String>) ft.getSection("hyperonyms"));
            }

            if (null != ft.getSection("hyponyms")) {
                term.setHyponyms((List<String>) ft.getSection("hyponyms"));
            }

            if (null != ft.getSection("meronyms")) {
                term.setMeronymes((List<String>) ft.getSection("meronyms"));
            }

            if (null != ft.getSection("related")) {
                term.setRelated((List<String>) ft.getSection("related"));
            }

            if (null != ft.getSection("synonymous")) {
                term.setSynonymous((List<String>) ft.getSection("synonymous"));
            }

            if (null != ft.getSection("translations")) {
                term.setTranslations((Map<String, List<String>>) ft.getSection("translations"));
            }

            if (null != ft.getSection("troponyms")) {
                term.setTroponyms((List<String>) ft.getSection("troponyms"));
            }

            if (null != ft.getSection("typographical_variants")) {
                term.setTypographicalVariants((List<String>) ft.getSection("typographical_variants"));
            }

            if (null != ft.getSection("variant_orthoraphic")) {
                term.setVariantOrthoraphic((List<String>) ft.getSection("variant_orthoraphic"));
            }

            if (null != ft.getSection("variants")) {
                term.setVariants((List<String>) ft.getSection("variants"));
            }

            if (null != ft.getSection("vocabulary")) {
                term.setVocabulary((List<String>) ft.getSection("vocabulary"));
            }
            return term;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * Save the given Term in the DB.
     *
     * @param term Term - The Term to save in the DB.
     */
    public void saveTerm(Term term) {
        try {
            service.insertTerm(term);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // Verifier si la traduction et le type existe bien
       /*
         * try { service.insertTerm(term); } catch (SQLException ex) {
         * Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, null, ex);
         * }
         */
    }

    /**
     * Save the relations of a Term in the DB.
     *
     * @param term Term - The relations of the Term to save in the DB.
     */
    public void saveRelation(Term term) {
        try {
            System.out.println("Process insert relations term : " + term.getTitle());
            service.insertTermRelations(term);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        /*
         * try { service.insertRelation(term); } catch (SQLException ex) {
         * Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, null, ex);
         * }
         */
    }

    /**
     * @see Parser#parser(boolean)
     */
    public void parserAndSaveTerm() {
        parser(true);
    }

    /**
     * @see Parser#parser(boolean)
     */
    public void parserAndSaveRelationTerm() {
        parser(false);
    }
}
